package com.itheima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.exception.config.IdWorkerConfig;
import com.heima.config.MinIOTemplate;
import com.heima.model.articleDto.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.entity.WmChannel;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.itheima.aliyun.AliyunGreenTemplate;
import com.itheima.feign.article.ArticleFeignClient;
import com.itheima.wemedia.dao.WmChannelDao;
import com.itheima.wemedia.dao.WmNewsDao;
import com.itheima.wemedia.dao.WmUserDao;
import com.itheima.wemedia.service.WmNewsAutoScanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {
    @Resource
    private WmNewsDao wmNewsDao;
    @Autowired
    private AliyunGreenTemplate aliyunGreenTemplate;
    @Autowired
    private MinIOTemplate minIOTemplate;
    @Autowired
    private WmChannelDao wmChannelDao;
    @Autowired
    private WmUserDao wmUserDao;
    @Autowired
    private ArticleFeignClient articleFeignClient;

    @Override
    public void autoScanNews(Long newsId) throws InvocationTargetException, IllegalAccessException {
        WmNews wmNews = wmNewsDao.queryById(newsId);
        if (wmNews == null) {
            throw new RuntimeException("文章数据不存在");
        }
        //获取图片文本
        HashMap<String, Object> wmNewImagesText = wmNewImagesText(wmNews);

        List<String> image = (List<String>) wmNewImagesText.get("image");
        StringBuilder text = (StringBuilder) wmNewImagesText.get("text");

        //自定义铭感词审核
        boolean sensitiveScan = handleSensitiveScan(text, wmNews);
        if (!sensitiveScan) {
            return;
        }

        //获取到图片url 调用阿里审核工具审核对应数据
        boolean imagesScan = wmNewImagesScan(image, wmNews);
        if (!imagesScan) {
            return;
        }
        //获取到文本 调用阿里审核工具审核对应数据
        boolean textScan = wmNewTextScan(text, wmNews);
        if (!textScan) {
            return;
        }

        if (wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            //小于就直接进行发布逻辑 如果已经到了用户设置的发布时间, 需要修改文章状态为9 , 并且发布文章
            saveArticle(wmNews);

        } else {
            //4. 审核通过, 修改文章状态
            updateStatus(wmNews, (short) 8, "审核通过");
        }
    }

    /**
     * 修改文章 状态为发布状态 发起远程feign远程调用发布文章
     * @param wmNews
     */
    public   ResponseResult saveArticle(WmNews wmNews) throws InvocationTargetException, IllegalAccessException {
        //判断对象是否为空
        if (wmNews==null||wmNews.getId()==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //对象拷贝到dto
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);
        articleDto.setNewsId(wmNews.getId());
        //  channelName频道昵称 authorName作者昵称 layout文章布局类型 需要手动赋值
        //根据频道id查询查询自媒体频道表
        WmChannel wmChannel = wmChannelDao.queryById(wmNews.getChannelId());
        if (wmChannel != null) {
            articleDto.setChannelName(wmChannel.getName());
        }

        //根据作者id查询 user昵称
        WmUser wmUser = wmUserDao.queryById(wmNews.getUserId().intValue());
        if(wmUser != null){
            articleDto.setAuthorName(wmUser.getNickname());
        }
        articleDto.setLayout(wmNews.getType().intValue());
        articleDto.setAuthorId(wmNews.getUserId());

        ResponseResult responseResult = articleFeignClient.save(articleDto);
        if (responseResult.getCode() == 200) {
            updateStatus(wmNews, (short) 9, "审核通过 , 已发布");
        }

        return responseResult;
    }

    /**
     * 自定义铭感词审核
     *
     * @param text
     * @param wmNews
     */
    private boolean handleSensitiveScan(StringBuilder text, WmNews wmNews) {
        if (text == null) {
            return true;
        }
        Map<String, Integer> result = SensitiveWordUtil.matchWords(text.toString());

        if (result.size() > 0) {
            updateStatus(wmNews, (short) 2, "文章内容中包含敏感词汇");
            return false;
        }
        return true;
    }

    /**
     * 审核文本
     *
     * @param text
     * @param wmNews
     */
    private boolean wmNewTextScan(StringBuilder text, WmNews wmNews) {
        if (text == null) {
            return true;
        }
        try {
            Map<String, String> result = aliyunGreenTemplate.greenTextScan(text.toString());
            if ("block".equals(result.get("suggestion"))) {
                updateStatus(wmNews, (short) 2, "文章内容中包含违规信息");
                return false;
            }
            if ("review".equals(result.get("suggestion"))) {
                updateStatus(wmNews, (short) 3, "文章内容中包不确定信息");
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            updateStatus(wmNews, (short) 3, "阿里云图片审核失败:" + e.getMessage());
            return false;
        }
    }

    /**
     * 审核图片
     *
     * @param image
     * @param wmNews
     */
    private boolean wmNewImagesScan(List<String> image, WmNews wmNews) {
        if (CollectionUtils.isEmpty(image)) {
            return true;
        }
        try {
            List<byte[]> bytes1 = new ArrayList<>();
            for (String url : image) {
                //调用minio获取该图片字节
                byte[] bytes = minIOTemplate.downLoadFile(url);
                bytes1.add(bytes);
            }

            //获取审核结果
            Map<String, String> result = aliyunGreenTemplate.greenImageScan(bytes1);
            if ("block".equals(result.get("suggestion"))) {
                updateStatus(wmNews, (short) 2, "图片内容中包含违规信息");
                return false;
            }
            if ("review".equals(result.get("suggestion"))) {
                updateStatus(wmNews, (short) 3, "图片内容中包不确定信息");
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            updateStatus(wmNews, (short) 3, "阿里云图片审核失败:" + e.getMessage());
            return false;
        }
    }

    /**
     * 修改状态
     *
     * @param wmNews
     * @param i
     * @param msg
     */
    private void updateStatus(WmNews wmNews, short i, String msg) {
        wmNews.setStatus(i);
        wmNews.setReason(msg);
        wmNewsDao.update(wmNews);
    }

    /**
     * 获取图片文本
     *
     * @param wmNews
     * @return
     */
    private HashMap<String, Object> wmNewImagesText(WmNews wmNews) {
        //创建两个集合 一个用来装图片一个用来封装文本
        StringBuilder texts = new StringBuilder();
        List<String> images = new ArrayList<>();

        //获取文章表头
        texts.append(wmNews.getTitle());
        //获取文本内容将 图片 文本分开
        List<Map> imageText = JSON.parseArray(wmNews.getContent(), Map.class);
        //循环获取map集合数据 对比字段获取图片跟文本
        if (!CollectionUtils.isEmpty(imageText)) {
            for (Map map : imageText) {
                if ("image".equals(map.get("type"))) {
                    images.add(map.get("value").toString());
                } else if ("text".equals(map.get("type"))) {
                    texts.append(map.get("value") + ",");
                }
            }
        }
        //获取文章封面
        String images1 = wmNews.getImages();
        if (images1 != null) {
            //不等于null就可以封装到集合 记住切割
            String[] split = images1.split(",");
            for (String s : split) {
                images.add(s);
            }
        }
        //创建map集合封装数据返回出去
        HashMap<String, Object> map = new HashMap<>();
        map.put("text", texts);
        map.put("image", images);
        return map;
    }
}
